package tests;

import static org.junit.Assert.*;

import java.util.Date;

import model.Lesson;
import model.Student;
import model.datasource.DataSource;
import model.datasource.DataSourceFactory;
import model.datasource.FilePlainTextDataSource;

import org.junit.Test;
import org.mockito.Mockito;

import common.Constants;

public class FileDataSourceTest {

	@Test
	public void addNewStudentTest()
	{
		DataSource ds = DataSourceFactory.getDataSource();
		assertNotNull(ds);
		assertTrue(ds instanceof FilePlainTextDataSource);
		String name = "Petar";
		String lastName = "Kovacevic";
		String nickName = "Pera";
		String email = "pera@yahoo.com";
		String phoneNumber = "0642332718";
		String school = "raf";
		int year = 1988;
		Student s = ds.addNewStudent(name, lastName, nickName, email, school, phoneNumber, year);
		
		assertTrue( s.getId() > 0 );
		assertEquals(s.getName(), name);
		assertEquals(s.getLastName(), lastName);
		assertEquals(s.getNickname(), nickName);
		assertEquals(s.getEmail(), email);
		assertEquals(s.getPhoneNumber(), phoneNumber);
		assertEquals(s.getSchool(), school);
		assertEquals(s.getAgeYear(), year);
	}
	
	@Test
	public void deleteStudentTest()
	{
		DataSource ds = DataSourceFactory.getDataSource();
		assertTrue(ds != null );
		
		int res = ds.deleteStudent(-10);
		assertEquals(res, Constants.ENTRY_NOT_FOUND);
		
		Student s = ds.addNewStudent("a", "b", "c", "d", "e", "f", 0);
		assertNotNull(s);
		assertTrue( s.getId() > 0 );
		
		res = ds.deleteStudent(s.getId());
		assertEquals(res, Constants.OK);
		
		java.util.Collection<Student> studs = ds.requestAllStudents();
		for( Student ss : studs )
		{
			assertTrue(ss.getId() != s.getId());
		}
	}
	
	@Test
	public void requestStudentsTest()
	{
		DataSource ds = DataSourceFactory.getDataSource();
		assertNotNull(ds);
		
		java.util.Collection<Student> studs = ds.requestAllStudents();
		assertNotNull(studs);
		
		if(studs.isEmpty())
		{
			ds.addNewStudent("pera", "peric", "pera", "pera@yahoo.com", "MG", "064", 1988);
			requestStudentsTest();
		}
		else
		{
			Student s = studs.iterator().next();
			assertNotNull(s);
		}		
	}
	
	@Test
	public void addNewLessonTest()
	{
		DataSource ds = DataSourceFactory.getDataSource();
		assertNotNull(ds);
		
		Student student = Mockito.mock(Student.class);
		Mockito.when(student.getId()).thenReturn(1);
		Mockito.when(student.getName()).thenReturn("Pera");
		
		assertEquals(student.getId(), 1);
		assertEquals(student.getName(), "Pera");
		
		Date d = new Date();
		int income = 3000;
		Lesson l = ds.addNewLesson(student, "OOP", "Objektno orjentisano programiranje", d, income);
		
		assertNotNull(l);
		assertTrue(l.getId() > 0);
	}
	
	@Test
	public void deleteLessonTest()
	{
		DataSource ds = DataSourceFactory.getDataSource();
		assertNotNull(ds);
		
		java.util.Collection<Lesson> lessons = ds.requestAllLessons();
		assertNotNull(lessons);
		
		if(lessons.isEmpty())
		{
			Student student = Mockito.mock(Student.class);
			Mockito.when(student.getId()).thenReturn(1);
			Mockito.when(student.getName()).thenReturn("Pera");
			
			assertEquals(student.getId(), 1);
			assertEquals(student.getName(), "Pera");
			
			Lesson l = ds.addNewLesson(student, "OOP", "Objektno orjentisano programiranje", new Date(), 3000);
			assertNotNull(l);
			
			lessons = ds.requestAllLessons();
		}
		
		Lesson l = lessons.iterator().next();
		assertNotNull(l);
		
		int res = ds.deleteLesson(l.getId());
		assertTrue(res == Constants.OK);
		
		lessons = ds.requestAllLessons();
		for( Lesson ll : lessons )
		{
			assertTrue(ll.getId() != l.getId()); // there is no lesson with l.id()
		}
	}
	
	@Test
	public void updateStudentTest()
	{
		DataSource ds = DataSourceFactory.getDataSource();
		assertNotNull(ds);
	
		java.util.Collection<Student> studs = ds.requestAllStudents();
		assertNotNull(studs);
		
		if(studs.isEmpty())
		{
			ds.addNewStudent("pera", "peric", "pera", "pera@yahoo.com", "MG", "064", 1988);
			updateStudentTest();
		}
		else
		{
			Student s = studs.iterator().next();
			assertNotNull(s);
			
			String m = "modified";
			String name = s.getName() + m;
			String nickName = s.getNickname() + m;
			String lastName = s.getLastName() + m;
			String email = s.getEmail() + m;
			String school = s.getSchool() + m;
			String phoneNumber = s.getPhoneNumber() + m;
			
			Student updatedStud = ds.updateStudent(s.getId(), name, lastName, nickName, email, school, phoneNumber, s.getAgeYear());
			assertNotNull(updatedStud);
			
			java.util.Collection<Student> updated = ds.requestAllStudents();
			boolean found = false;
			for(Student ss : updated)
			{
				if(ss.getId() == updatedStud.getId())
				{
					found = true;
					assertEquals(name, ss.getName());
					assertEquals(nickName, ss.getNickname());
					assertEquals(lastName, ss.getLastName());
					assertEquals(email, ss.getEmail());
					assertEquals(school,  ss.getSchool());
					assertEquals(phoneNumber, ss.getPhoneNumber());
				}
			}
			
			assertTrue(found);
			
		}
	}
	
	@Test
	public void updateLessonTest()
	{
		DataSource ds = DataSourceFactory.getDataSource();
		assertNotNull(ds);
	
		java.util.Collection<Lesson> lessons = ds.requestAllLessons();
		assertNotNull(lessons);
		
		Student student = Mockito.mock(Student.class);
		Mockito.when(student.getId()).thenReturn(1);
		Mockito.when(student.getName()).thenReturn("Pera");
		
		assertEquals(student.getId(), 1);
		assertEquals(student.getName(), "Pera");
		
		if(lessons.isEmpty())
		{						
			ds.addNewLesson(student, "title", "content", new Date(), 1000);			
			updateLessonTest();
		}
		else
		{
			Lesson l = lessons.iterator().next();
			assertNotNull(l);
			
			String m = "modified";
			String title = l.getTitle() + m;
			String content = l.getContent() + m;
			Date date = new Date(l.getDate().getTime() + 172800000 ); // new date is 2 days after
			int income = l.getIncome() + 10;
						
			Lesson updatedLesson = ds.updateLesson(l.getId(), student, title, content, date, income);
			assertNotNull(updatedLesson);
			
			java.util.Collection<Lesson> updated = ds.requestAllLessons();
			boolean found = false;
			for(Lesson ll : updated)
			{
				if(ll.getId() == updatedLesson.getId())
				{
					found = true;
					assertEquals(title, ll.getTitle());
					assertEquals(content, ll.getContent());
					assertEquals(date, ll.getDate());
					assertEquals(income, ll.getIncome());
				}
			}
			
			assertTrue(found);
			
		}
	}
}
